﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Unity;
using Infrastucture;
using TimeSplicerModule.Factories;
using TimeSplicerModule.DomainModels;
using TimeSplicerModule.Security;
using TimeSplicerModule.ViewModels;

namespace TimeSplicerModule.Services
{
    public interface ITeamService
    {
        TeamViewModel CreateNew();
        TeamViewModel Get(Guid teamGuid);
        TeamViewModel Save(TeamViewModel model);
        TeamListViewModel GetTeamListViewModel();
        List<TeamModel> GetViewableTeams();
    }

    public class TeamService : ITeamService
    {
        private readonly IUnityContainer _container;
        private ISession _session;
        private readonly ITeamFactory _teamFactory;

        public TeamService(IUnityContainer container, ITeamFactory teamFactory)
        {
            _container = container;
            _teamFactory = teamFactory;
        }

        public TeamViewModel CreateNew()
        {
            // todo: need to set default parent
            _session = _container.Resolve<ISession>();
            var team = _teamFactory.CreateNew();
            team.IsActive = true;


            team.Teams = GetViewableTeams();

            if (team.Teams != null && team.Teams.Count > 0)
            {
                team.ParentTeam = team.Teams.OrderBy(o => o.Y).FirstOrDefault();
                team.ParentTeamGuid = team.ParentTeam.ParentTeamGuid;
                team.Y = team.ParentTeam.Y + 1;
                team.X = team.X; // dont think this will work exactly, need to check position, for now just create teams in db
            }


            var model = ModelConverter.ToModel<TeamViewModel>(team);

            return model;
        }

        public TeamViewModel Get(Guid teamGuid)
        {
            _session = _container.Resolve<ISession>();

            if (_session != null && _session.User != null)
            {
                if (_session.User.Team == null)
                    _session.User.Team = _teamFactory.Get(x => x.TeamGuid == _session.User.TeamGuid);
   
                var team = _teamFactory.Get(x => x.TeamGuid == teamGuid);
                if (team.X >= _session.User.Team.X && team.Y >= _session.User.Team.Y)
                {
                    team.Teams = GetViewableTeams();
                    var model = ModelConverter.ToModel<TeamViewModel>(team);

                    return model;
                }
            }

            return null;
        }

        public TeamViewModel Save(TeamViewModel model)
        {
            _session = _container.Resolve<ISession>();

            var parent = model.Teams.FirstOrDefault(x => x.TeamGuid == model.ParentTeamGuid);

            model.X = parent.X + 1;
            model.Y = parent.Y + 1;

            var team = ModelConverter.ToModel<TeamModel>(model);
            team = _teamFactory.Upsert(team);


            return Get(team.TeamGuid);
        }

        public TeamListViewModel GetTeamListViewModel()
        {
            _session = _container.Resolve<ISession>();
            TeamListViewModel model = new TeamListViewModel();

            if (_session != null && _session.User != null)
            {
                model.Teams = GetViewableTeams();
            }

            return model;
        }

        public List<TeamModel> GetViewableTeams()
        {
            _session = _container.Resolve<ISession>();

            if (_session != null && _session.User != null)
            {
                if (_session.User.Team == null)
                    _session.User.Team = _teamFactory.Get(x => x.TeamGuid == _session.User.TeamGuid);

                var teams = _teamFactory.GetList(x => x.X >= _session.User.Team.X
                    && x.Y >= _session.User.Team.Y);

                return teams;
            }


            return null;
        }
    }
}
